package com.bigdata.demo.Utils;

import com.bigdata.demo.methods.Connection_BigData;
import com.bigdata.demo.methods.Public;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;

import static com.bigdata.demo.methods.Connection_BigData.Name;

public class utils {
    //更新列表
    public String[][] findAll() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss ");
        File dir = new File(Public.Calculation_File_dir_server);
        File []children = dir.listFiles();
        int count=0,j=0;
        for(int i=0;i<children.length;i++){
            if(children[i].isDirectory()&&!children[i].getName().equals("temporary"))
                count++;
        }
        String[][] arr = new String[count][5];
        for (int i = 0; i < children.length; i++) {
            if(children[i].isDirectory()&&!children[i].getName().equals("temporary")){
                //计算名称
                String foldername = children[i].getName();
                //文件名
                File file = new File(Public.Calculation_File_dir_server+"/"+foldername);
                File []files = file.listFiles();
                String filename,prefix= "";
                assert files != null;
                for (File value : files) {
                    filename = value.getName();
                    if (filename.substring(filename.lastIndexOf(".")).equals(".py")) {
                        prefix = (filename.substring(0, filename.lastIndexOf(".")));
                        break;
                    }
                }
                //文件大小
                long size = getFileSize(file);    //递归计算文件夹大小
                String Size;
                DecimalFormat df=new DecimalFormat("0.00");
                if(size<1024){
                    Size = String.valueOf(size)+"字节";
                }else if(size>=1024&&size<Math.pow(1024,2)){
                    Size = df.format(size/1024.0)+"kb";
                }else if(size>=Math.pow(1024,2)&&size<Math.pow(1024,3)){
                    Size = df.format(size/1024.0*1024)+"M";
                }else {
                    Size = df.format(size/1024.0*1024*1024);
                }
                //创建时间
                FileTime t = null;
                try {
                    String filePath = children[i].getPath();
                    t = Files.readAttributes(Paths.get(filePath), BasicFileAttributes.class).creationTime();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                arr[j][0] = foldername;
                arr[j][1]= prefix;
                arr[j][2]= String.valueOf(t.toMillis());
                arr[j][3] = "科大老学长";
                arr[j][4] = Size;
                j++;
            }
        }
        //对数组根据创建时间排序
        arr = arrSort(arr);
        //将创建时间转化为"YYYY-MM-dd HH:mm:ss "形式
        for(int i=0;i<arr.length;i++) {
            arr[i][2] = dateFormat.format(Long.parseLong((arr[i][2])));
        }
        return arr;
    }
    //获取有参数的列表
    public String[][] findQuery(String[][] arr, String query) {
        int count = 0;
        for (String[] item : arr) {
            if (item[0].indexOf(query)!=-1){
                count++;
            }
        }
        String [][]arrQuery = new String[count][5];
        int j = 0;
        for (String[] item : arr) {
            if (item[0].indexOf(query)!=-1){
                arrQuery[j]=item;
                j++;
            }
        }
        System.out.println("count    "+count);
        return arrQuery;
    }
    //更新页面---递归获取计算文件夹大小
    private long getFileSize(File f) {
        long size = 0;
        File flist[] = f.listFiles();
        for (int i = 0; i < flist.length; i++)
        {
            if (flist[i].isDirectory())
            {
                size = size + getFileSize(flist[i]);
            } else
            {
                size = size + flist[i].length();
            }
        }
        return size;
    }
    //更新页面---对获取的二维数组根据创建时间进行排序
    private String[][] arrSort(String[][] arr) {
        String []index;
        for(int i=0;i<arr.length-1;i++){
            for(int j=i+1;j<arr.length;j++){
                if(Long.parseLong((arr[i][2]))<Long.parseLong((arr[j][2]))){
                    index = arr[i];
                    arr[i] = arr[j];
                    arr[j] = index;
                }
            }
        }
        return arr;
    }
    //上传文件
    public String uploadFile(MultipartFile file,String filePath){
        if(file == null){
            return "error";
        }
        String fileName = file.getOriginalFilename();
        String prefix = (fileName.substring(0,fileName.lastIndexOf("."))); // 前缀
        String suffix= fileName.substring(fileName.lastIndexOf(".")); // 后缀
//        String newFileName = prefix+"_"+ UUID.randomUUID();
        String newFileName = prefix+suffix;
        //判断该文件夹下是否有重名文件
        File dir = new File(Public.Calculation_File_dir_server);
        String[] children = dir.list();
        if (children == null) {
            System.out.println( "目录不存在或它不是一个目录");
            return "error";
        }
        else{
            for (int i=0; i< children.length; i++) {
                if(children[i].equals(newFileName)){
                    System.out.println("文件"+newFileName+"重复...将暂存入缓存文件夹");
                    System.out.println("文件路径为："+Public.Calculation_File_dir_server_temporary+"/"+newFileName);
                    File dest = new File(Public.Calculation_File_dir_server_temporary+"/"+newFileName);
                    try {
                        file.transferTo(dest);//存储文件
                        System.out.println("暂存文件成功");
                        return newFileName+" repetition";
                    } catch (IOException e) {
                        throw new RuntimeException("暂存文件失败，服务器发生异常", e);
                    }
                }
            }
        }
        /**
         * 为了避免上传文件重复，这里加入了一个唯一的编号UUID，
         * 生成随机文件名,存到本机位置
         */
        System.out.println("文件路径为："+filePath+"/"+newFileName);
        File dest = new File(filePath+"/"+newFileName);
        try {
            file.transferTo(dest);//存储文件
            System.out.println("上传文件成功");
            return newFileName+" success";
        } catch (IOException e) {
            throw new RuntimeException("上传文件失败，服务器发生异常", e);
        }
    }
    //执行计算
    public static String run_upload_python(String filename,String catalog) {
//        Runtime runtime = Runtime.getRuntime();
//        String []command = null;
//        File file = new File(catalog);
////        System.out.println("command = "+command);
//        try {
////            Runtime.getRuntime().exec("cd "+catalog+"");
////            Runtime.getRuntime().exec("python3 "+filename+"", null,file);
//            BufferedReader br = new BufferedReader(
//                    new InputStreamReader(
//                            runtime.exec("python3 "+filename+"", null,file).getInputStream(),
//                            "GB2312"
//                    )
//            );
//            String line;
//            StringBuilder b = new StringBuilder();
//            while ((line = br.readLine()) != null) {
//                b.append(line).append("\n");
//                System.out.println("line = "+line);
//            }
//            System.out.println("执行结果："+b);
//            return b;
//        } catch (Exception e) {
//            e.printStackTrace();
//            return null;
//        }
        String hostname = Public.hostname_bigdata;//要连接主机的ip
        String username = Public.username_bigdata;//登录的用户名
        String password = Public.password_bigdata;  //用户密码
        String pri; //接口的返回，运行状态

        //调用封装的类Connection_BigData，远程连接集群
        Connection_BigData con = new Connection_BigData(hostname, username, password);
        String cmd="docker exec -it python /bin/bash ; ";
        cmd += "cd "+catalog+"; ";
        cmd += "python3 "+filename;

        System.out.println("cmd:"+cmd);  //可以打印出来，看命令是否正确
        pri = con.connection(cmd); //调用函数connection，连接集群，并执行cmd命令，返回运行状态
        System.out.println("pri: "+pri);
        return "success";
    }
    //上传文件---覆盖文件
    public String replaceFile(String filename) throws IOException {
        File cache = new File(Public.Calculation_File_dir_server_temporary+"/"+filename);
        File target = new File(Public.Calculation_File_dir_server+"/"+filename);
        copyFile(cache,target);
        cache.delete();
        return filename;
    }
    //复制文件
    private void copyFile(File calfile, File target) throws IOException {
        target.delete();
        target.createNewFile();
        FileInputStream fis = new FileInputStream(calfile);
        FileOutputStream fos = new FileOutputStream(target);
        // 读写数据
        // 定义数组
        byte[] b = new byte[1024];
        // 定义长度
        int len;
        // 循环读取
        while ((len = fis.read(b))!=-1) {
            // 写出数据
            fos.write(b, 0 , len);
        }
        //关闭资源
        fos.close();
        fis.close();
    }
    //上传文件---清除缓存文件
    public String deletecache(String filename) {
        File cache = new File(Public.Calculation_File_dir_server_temporary+"/"+filename);
        cache.delete();
        return "清除成功";
    }
   //创建计算
    public void copyfile(String calname, String calfilename) throws IOException {
        String filePath = Public.Calculation_File_dir_server;
        File file = new File(filePath+"/"+calname);
        file.mkdir();
        String catalog = filePath+"/"+calname;
        File calfile = new File(filePath+"/"+calfilename+".py");
        File target = new File(catalog+"/"+calfilename+".py");
        copyFile(calfile,target);
//        String s = run_upload_python(target.getName(),catalog);
//        String s = run_upload_python("test02.py","/home/bigdata_platform/computation/test02");
//        System.out.println(s);
    }
   //创建计算---获取可执行python文件名
    public String[] acquirefile() {
        int count=0,j=0;
        File file = new File(Public.Calculation_File_dir_server);
        File []chiledren = file.listFiles();
        for(int i=0;i<chiledren.length;i++){
            if(chiledren[i].isFile()&&chiledren[i].getName().substring(chiledren[i].getName().lastIndexOf(".")).equals(".py")){
                count++;
        }
        }
        String []arr = new String[count];
        for(int i=0;i<chiledren.length;i++){
            if(chiledren[i].isFile()&&chiledren[i].getName().substring(chiledren[i].getName().lastIndexOf(".")).equals(".py")){
                String filename=chiledren[i].getName();
                arr[j] = filename.substring(0,filename.lastIndexOf("."));
                j++;

            }
        }
        return arr;
     }

    //找pod名字
    public String find_pod(String deployment,String namespace) {

        String hostname = Public.hostname_bigdata;//要连接主机的ip
        String username = Public.username_bigdata;//登录的用户名
        String password = Public.password_bigdata;  //用户密码
        String pri; //接口的返回，运行状态
        //调用封装的类Connection_BigData，远程连接集群
        Connection_BigData con = new Connection_BigData(hostname, username, password);
        String path = Public.SHELL_dir;   //脚本所在目录
        String cmd="cd "+path+"; ";                   //找到脚本所在目录

        //拼接命令，例如：/bin/bash container_find_all.sh bigdata-platform
        String shell_name = "find_pod.sh ";             //脚本名
        //每个参数后面接空格，这里表示将这些参数传给脚本
        shell_name += namespace +' '+deployment;
        cmd += "/bin/bash "+shell_name;              //脚本执行的命令

        System.out.println("cmd:"+cmd);  //可以打印出来，看命令是否正确
        pri = con.connection(cmd); //调用函数connection，连接集群，并执行cmd命令，返回运行状态

        String pod = Name.get(0);
        return pod;
    }
    //计算
    public void caozuo(String calname, String calfilename, String pod, String namespace, String deployment) {

        String hostname = Public.hostname_bigdata;//要连接主机的ip
        String username = Public.username_bigdata;//登录的用户名
        String password = Public.password_bigdata;  //用户密码
        String pri; //接口的返回，运行状态

        //调用封装的类Connection_BigData，远程连接集群
        Connection_BigData con = new Connection_BigData(hostname, username, password);
        String folderpath = Public.Calculation_File_dir_server+"/"+calname;
        String folderpath2 = Public.Calculation_File_dir_server2+"/"+calname;
        String filepath = folderpath+"/"+calfilename+".py";
        String filepath2 = folderpath2+"/"+calfilename+".py";
        String shellpath = Public.SHELL_dir;
        String shellpath2 = Public.SHELL_dir2;
        //在容器内创建目录
        String cmd = "/bin/bash "+shellpath+"/create_directory.sh "+pod+" "+namespace+" "+folderpath+" "+shellpath+" ; ";
        //将主机文件拷贝到pod
        cmd += "kubectl cp "+filepath+" -n "+namespace+" "+pod+":"+filepath2+" ; ";
        cmd += "kubectl cp "+shellpath+"/exec_docker_calfile.sh -n "+namespace+" "+pod+":"+shellpath2+"/exec_docker_calfile.sh ; ";
        cmd += "kubectl cp "+shellpath+"/delete-container-file.sh -n "+namespace+" "+pod+":"+shellpath2+"/delete-container-file.sh ; ";
////        //执行文件并复制到主机
        cmd += "/bin/bash "+shellpath+"/cal_copy_to_host.sh "+pod+" "+namespace+" "+shellpath+" "+folderpath+" "+calfilename+" "+folderpath2+" ; ";
        //还原容器
        cmd += "kubectl exec -it "+pod+" -n "+namespace+" /bin/bash -- /bin/bash "+shellpath+"/delete-container-file.sh ; ";
//         String cmd = "kubectl exec -it "+container+" -c python -n bigdata-platform /bin/bash -- mkdir -p /home/bigdata_platform/computation/64 ;";
//         cmd += "kubectl cp "+filepath+" -n bigdata-platform -c python "+container+":"+filepath+" ; ";
//         cmd += "kubectl exec -it "+container+" -c python -n bigdata-platform /bin/bash -- python3 /home/bigdata_platform/computation/64/test3.py";
//        String cmd = "kubectl exec -it "+container+" -c python -n bigdata-platform /bin/bash -- python3 /home/bigdata_platform/computation/64/test3.py";
        System.out.println("cmd:"+cmd);  //可以打印出来，看命令是否正确
        pri = con.connection(cmd); //调用函数connection，连接集群，并执行cmd命令，返回运行状态

    }

    //编辑
    public void editFoldername(String foldername, String tofoldername) {
        String hostname = Public.hostname_bigdata;//要连接主机的ip
        String username = Public.username_bigdata;//登录的用户名
        String password = Public.password_bigdata;  //用户密码
        String pri; //接口的返回，运行状态
        //调用封装的类Connection_BigData，远程连接集群
        Connection_BigData con = new Connection_BigData(hostname, username, password);
        String path = Public.Calculation_File_dir_server;
        String cmd="cd "+path+"; ";
        cmd += "mv "+foldername+" "+tofoldername;              //脚本执行的命令

        System.out.println("cmd:"+cmd);  //可以打印出来，看命令是否正确
        pri = con.connection(cmd); //调用函数connection，连接集群，并执行cmd命令，返回运行状态
        System.out.println(pri);
    }

    //删除
    public void deleteFoldername(String foldername) {
        String hostname = Public.hostname_bigdata;//要连接主机的ip
        String username = Public.username_bigdata;//登录的用户名
        String password = Public.password_bigdata;  //用户密码
        String pri; //接口的返回，运行状态
        //调用封装的类Connection_BigData，远程连接集群
        Connection_BigData con = new Connection_BigData(hostname, username, password);
        String path = Public.Calculation_File_dir_server;
        String cmd="cd "+path+"; ";
        cmd += "rm -rf "+foldername;              //脚本执行的命令

        System.out.println("cmd:"+cmd);  //可以打印出来，看命令是否正确
        pri = con.connection(cmd); //调用函数connection，连接集群，并执行cmd命令，返回运行状态
        System.out.println(pri);
    }
}


